package com.cg.service;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.cg.business.CGUserController;
import com.cg.client.Rides;
import com.cg.util.CGUtilClass;
import com.google.gson.Gson;

public class GetCGUsers extends HttpServlet{
	
	private static final long serialVersionUID = 1L;
	private String servletContext = "";
	private static Log log = LogFactory.getLog(GetCGUsers.class.getName());
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(request, response);
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String startTime = null;
		String endTime = null;
		String checkBoxTransportModes = null;
		int startRadius = 0;
		int endRadius = 0;
		String startLat = null;
		String startLng = null;
		String endLat = null;
		String endLng = null;
		
		
		log.info("Inside GetCGUsers servlet");
		
		//String startLat = "57.70000";
		//String startLng = "11.93333";
		//String endLat = "57.7071256";
		//String endLng =  "11.9397962";//11.93333, 57.70000  11.9397962  57.7071256
		
		
		if(request.getParameter("slat")!=null && request.getParameter("slng")!=null
		&& request.getParameter("elat")!=null && request.getParameter("elng")!=null
		&& request.getParameter("startRadius")!= null&& request.getParameter("endRadius")!= null  
		&& request.getParameter("startDate")!= null && request.getParameter("endDate")!= null 
		&& request.getParameter("checkBoxVal")!=null){
			
			startLat = request.getParameter("slat");
			startLng = request.getParameter("slng");
			endLat = request.getParameter("elat");
			endLng = request.getParameter("elng");
			startRadius= Integer.parseInt(request.getParameter("startRadius").toString())*1000;
			endRadius= Integer.parseInt(request.getParameter("endRadius").toString())*1000;
			startTime = request.getParameter("startDate").toString();
			endTime = request.getParameter("endDate").toString();
			checkBoxTransportModes = request.getParameter("checkBoxVal").toString();
			
			HttpSession session = request.getSession(true);
			session.setAttribute("startLat", startLat);
			session.setAttribute("startLng", startLng);
			session.setAttribute("endLat", endLat);
			session.setAttribute("endLng", endLng);
			session.setAttribute("startRadius", startRadius);
			session.setAttribute("endRadius", endRadius);
			session.setAttribute("startTime", startTime);
			session.setAttribute("endTime", endTime);
			session.setAttribute("checkBoxTransportModes", checkBoxTransportModes);
			
			log.debug("Start Lat: "+ startLat + "  " +
					  "Start Lng: "+ startLng + "  " +
					  "End Lat: "+ endLat + "  " +
					  "End Lng: " + endLng + "  " +
					  "Start Radius: "+ startRadius + "  " +
					  "End Radius: "+ endRadius + "  " +
					  "Start Date: "+ startTime + "  " +
					  "End Date: "+ endTime + "  " +
					  "Transport: "+ checkBoxTransportModes);
					} 
	
		String[] temp = null;
		if(checkBoxTransportModes!=null){
			String str = checkBoxTransportModes;
			/* delimiter */
			String delimiter = " ";
			/* given string will be split by the argument delimiter provided. */
			temp = str.split(delimiter);
			temp[0] = temp[0].substring(4);
			/* print substrings */
			for(int i =0; i < temp.length ; i++)
				
				log.debug("Transport Modes: "+temp[i]);
			
		}
		
		if(startLat != null && startLat.length() > 0 &&  
		    startLng !=null && startLng.length() > 0 && 
			endLat != null && endLat.length() > 0 && 
			endLng!=null && endLng.length() > 0 &&
			startRadius !=0 && startRadius > 0 &&
			endRadius !=0 && endRadius > 0 &&
		    startTime!=null && startTime.length() > 0 &&
			endTime !=null && endTime.length() > 0) {
		
		try {
			CGUserController controller = new CGUserController();
			ArrayList<String> latLongList = new ArrayList<String>();
			ArrayList<String> latLongDest = new ArrayList<String>();
			ArrayList<String> finalJourneyList = new ArrayList<String>();
			ArrayList<String> rideCategoryList = new ArrayList<String>();
			Rides ride = new Rides();
			String imgUrlCar = null;
			String iconUrlCar = null;
			String imgUrlBus = null;
			String iconUrlBus = null;
			String imgUrlBicycle = null;
			String iconUrlBicycle = null;
			String imgUrlWalking = null;
			String iconUrlWalking = null;
			String imgUrlTrain = null;
			String iconUrlTrain = null;
			String imgUrlFerry = null;
			String iconUrlFerry = null;
			String imgUrlAeroplane = null;
			String iconUrlAeroplane = null;
			
			// Calling
			List<Rides> respRideList= controller.getMatchingCGJourneys(Double.parseDouble(startLat), Double.parseDouble(startLng), startRadius, Double.parseDouble(endLat), Double.parseDouble(endLng), endRadius , com.cg.util.DataUtil.convertDate(startTime), com.cg.util.DataUtil.convertDate(endTime),temp);
			int totalCo2Car = 0;
			int totalCo2Bus = 0;
			int totalCo2Walking = 0;
			int totalCo2Bicycle = 0;
			int totalCo2Train = 0;
			int totalCo2Ferry = 0;
			int totalCo2Aeroplane = 0;
			int totalDistanceCar = 0;
			int totalDistanceBicycle = 0;
			int totalDistanceWalking = 0;
			int totalDistanceBus = 0;
			int totalDistanceFerry = 0;
			int totalDistanceTrain = 0;
			int totalDistanceAeroplane = 0;
			int journeyCount = 0;
			
			for(int i = 0;i<respRideList.size();i++){
				if(respRideList.get(i).getId()!=null){
					journeyCount++;
				}
			}
			log.info("Total no of journeys"+journeyCount);
			request.setAttribute("journeyCount", journeyCount);
		
			for(int i = 0;i<respRideList.size();i++){
				totalCo2Car = totalCo2Car+respRideList.get(i).getGrammesCO2Car();				
			}			
			for(int i = 0;i<respRideList.size();i++){
				totalCo2Bus = totalCo2Bus+respRideList.get(i).getGrammesCO2Bus();	
			}
			for(int i = 0;i<respRideList.size();i++){
				totalCo2Walking = totalCo2Walking+respRideList.get(i).getGrammesCO2Walking();	
			}
			for(int i = 0;i<respRideList.size();i++){
				totalCo2Bicycle = totalCo2Bicycle+respRideList.get(i).getGrammesCO2Bicycle();	
			}
			for(int i = 0;i<respRideList.size();i++){
				totalCo2Train = totalCo2Train+respRideList.get(i).getGrammesCO2Train();	
			}
			for(int i = 0;i<respRideList.size();i++){
				totalCo2Ferry = totalCo2Ferry+respRideList.get(i).getGrammesCO2Ferry();	
			}
			for(int i = 0;i<respRideList.size();i++){
				totalCo2Aeroplane = totalCo2Aeroplane+respRideList.get(i).getGrammesCO2Aeroplane();	
			}
			
			
		   int totalCo2 = totalCo2Car+totalCo2Bus+totalCo2Walking+totalCo2Bicycle+totalCo2Train+totalCo2Ferry+totalCo2Aeroplane;
		   

		   for(int i = 0;i<respRideList.size();i++){
			   totalDistanceCar = totalDistanceCar+respRideList.get(i).getDistanceCar();	
			}
		   
		   for(int i = 0;i<respRideList.size();i++){
			   totalDistanceBicycle = totalDistanceBicycle+respRideList.get(i).getDistanceBicycle();	
			}
		   
		   for(int i = 0;i<respRideList.size();i++){
			   totalDistanceBus = totalDistanceBus+respRideList.get(i).getDistanceBus();	
			}
		   for(int i = 0;i<respRideList.size();i++){
			   totalDistanceWalking = totalDistanceWalking+respRideList.get(i).getDistanceWalking();	
			}
		   
		   for(int i = 0;i<respRideList.size();i++){
			   totalDistanceFerry = totalDistanceFerry+respRideList.get(i).getDistanceFerry();	
			}
		   for(int i = 0;i<respRideList.size();i++){
			   totalDistanceTrain = totalDistanceTrain+respRideList.get(i).getDistanceTrain();	
			}
		   for(int i = 0;i<respRideList.size();i++){
			   totalDistanceAeroplane = totalDistanceAeroplane+respRideList.get(i).getDistanceAeroplane();	
			}
			
		   
		   int totalDistance = totalDistanceCar+totalDistanceBicycle+totalDistanceBus+totalDistanceWalking+totalDistanceFerry+totalDistanceTrain+totalDistanceAeroplane;
		   
		   // Getting the segment percentages
		   double bicycleDistPercentage = Math.floor(((double)totalDistanceBicycle/totalDistance)*100);
		   int percentageBicycleKM = (int)bicycleDistPercentage;
		   		   
		   double carDistPercentage = Math.floor(((double)totalDistanceCar/totalDistance)*100);
		   int percentageCarKM = (int)carDistPercentage;
		  
		   double walkingDistPercentage = Math.floor(((double)totalDistanceWalking/totalDistance)*100);
		   int percentageWalkingKM = (int)walkingDistPercentage;
		   
		   double busDistPercentage = Math.floor(((double)totalDistanceBus/totalDistance)*100);
		   int percentageBusKM = (int)busDistPercentage;
		   
		   double ferryDistPercentage = Math.floor(((double)totalDistanceFerry/totalDistance)*100);
		   int percentageFerryKM = (int)ferryDistPercentage;
		   
		   double trainDistPercentage = Math.floor(((double)totalDistanceTrain/totalDistance)*100);
		   int percentageTrainKM = (int)trainDistPercentage;
		   
		   double aeroplaneDistPercentage = Math.floor(((double)totalDistanceAeroplane/totalDistance)*100);
		   int percentageAeroplaneKM = (int)aeroplaneDistPercentage;
		   
		
		   
		   for(int i = 0;i<respRideList.size();i++){
			   rideCategoryList.add(respRideList.get(i).getCategory());
			  
			   if(respRideList.get(i).getCategory()!=null && respRideList.get(i).getCategory().equalsIgnoreCase("Car")){
				   imgUrlCar = "images/co2CarM.png";
				   iconUrlCar ="images/red.png";	
				}
				if(respRideList.get(i).getCategory()!=null && respRideList.get(i).getCategory().equalsIgnoreCase("Bus")){
					imgUrlBus = "images/co2Bus.png";
					iconUrlBus ="images/black.png";
				}
				if(respRideList.get(i).getCategory()!=null && respRideList.get(i).getCategory().equalsIgnoreCase("Bicycle")){
					imgUrlBicycle = "images/co2Bicycle.png";
					iconUrlBicycle ="images/green.png";
				}
				if(respRideList.get(i).getCategory()!=null && respRideList.get(i).getCategory().equalsIgnoreCase("Walking")){
					imgUrlWalking = "images/co2Walking.png";
					iconUrlWalking ="images/purple.png";
					
				}
				if(respRideList.get(i).getCategory()!=null && respRideList.get(i).getCategory().equalsIgnoreCase("TRAIN_SUBWAY_METRO")){
					imgUrlTrain = "images/co2Train.png";
					iconUrlTrain ="images/pink.png";
					
				}
				if(respRideList.get(i).getCategory()!=null && respRideList.get(i).getCategory().equalsIgnoreCase("Ferry")){
					imgUrlFerry = "images/co2Ferry.png";
					iconUrlFerry ="images/blue.png";
					
				}
				if(respRideList.get(i).getCategory()!=null && respRideList.get(i).getCategory().equalsIgnoreCase("Aeroplane")){
					imgUrlAeroplane = "images/co2Aeroplane.png";
					iconUrlAeroplane ="images/silver.png";
					
				}
			}
		   
	   for(int i = 0;i<respRideList.size();i++){
		   
		   if(respRideList.get(i).getCategory()!=null){
		   
		       latLongList.add(Double.toString(respRideList.get(i).getStartAddressGpslat()));
			   latLongList.add(Double.toString(respRideList.get(i).getStartAddressGpslng()));
		       latLongList.add(respRideList.get(i).getCategory());
		   }
			   
		   }
		 	   
		   
		   for(int i = 0;i<respRideList.size();i++){
			   if(respRideList.get(i).getCategory()!=null){
				  
			   latLongDest.add(Double.toString(respRideList.get(i).getEndAddressGpslat()));
			   latLongDest.add(Double.toString(respRideList.get(i).getEndAddressGpslng()));
			   latLongDest.add("DESTINATION");
			   }
		   }
		   
		   latLongList.addAll(latLongDest);//merging the two Arraylists of segments and destinations
		 //  finalJourneyList.addAll(latLongList);
		 //  finalJourneyList.addAll(latLongDest);
		   
		   
			String pathNew = getServletContext().getRealPath("/js/");  
			log.debug("Path for xml: " + pathNew);
		    
			CGUtilClass utilObj = new CGUtilClass();
			utilObj.WriteXml(latLongList,pathNew,"\\startLocation.xml");
		   
		    
			request.setAttribute("totalCo2Car", totalCo2Car);
			request.setAttribute("totalCo2Bus", totalCo2Bus);
			request.setAttribute("totalCo2Walking", totalCo2Walking);
			request.setAttribute("totalCo2Bicycle", totalCo2Bicycle);
			request.setAttribute("totalCo2Train", totalCo2Train);
			request.setAttribute("totalCo2Ferry", totalCo2Ferry);
			request.setAttribute("totalCo2Aeroplane", totalCo2Aeroplane);
			request.setAttribute("imgUrlCar",imgUrlCar);
			request.setAttribute("iconUrlCar",iconUrlCar);
			request.setAttribute("imgUrlBus",imgUrlBus);
			request.setAttribute("iconUrlBus",iconUrlBus);
			request.setAttribute("imgUrlBicycle",imgUrlBicycle);
			request.setAttribute("iconUrlBicycle",iconUrlBicycle);
			request.setAttribute("imgUrlWalking",imgUrlWalking);
			request.setAttribute("iconUrlWalking",iconUrlWalking);
			request.setAttribute("imgUrlTrain",imgUrlTrain);
			request.setAttribute("iconUrlTrain",iconUrlTrain);
			request.setAttribute("imgUrlFerry",imgUrlFerry);
			request.setAttribute("iconUrlFerry",iconUrlFerry);
			request.setAttribute("imgUrlAeroplane",imgUrlAeroplane);
			request.setAttribute("iconUrlAeroplane",iconUrlAeroplane);
			request.setAttribute("totalCo2", totalCo2);
			request.setAttribute("ride",ride);
			request.setAttribute("totalDistanceCar",totalDistanceCar);
			request.setAttribute("totalDistanceBus",totalDistanceBus);
			request.setAttribute("totalDistanceBicycle",totalDistanceBicycle);
			request.setAttribute("totalDistanceWalking",totalDistanceWalking);
			request.setAttribute("totalDistanceFerry",totalDistanceFerry);
			request.setAttribute("totalDistanceAeroplane",totalDistanceAeroplane);
			request.setAttribute("totalDistanceTrain",totalDistanceTrain);
			request.setAttribute("totalDistance", totalDistance);
			request.setAttribute("percentageCarKM", percentageCarKM);
			request.setAttribute("percentageBicycleKM", percentageBicycleKM);
			request.setAttribute("percentageWalkingKM", percentageWalkingKM);
			request.setAttribute("percentageBusKM", percentageBusKM);
			request.setAttribute("percentageFerryKM", percentageFerryKM);
			request.setAttribute("percentageAeroplaneKM", percentageAeroplaneKM);
			request.setAttribute("percentageTrainKM", percentageTrainKM);
			
			
			
			
			
			
			
			request.setAttribute("rideList", respRideList);
			
			Gson gson = new Gson();
			String journeyJson = gson.toJson(respRideList);
			request.setAttribute("journeyJson", journeyJson);
			
			
			log.debug("API Json response :"+journeyJson);
			String destination = "/jsp/SearchResults.jsp";
			//response.setContentType("application/json");
			// Get the printwriter object from response to write the required json object to the output stream      
			//PrintWriter out = response.getWriter();
			// Assuming your json object is **jsonObject**, perform the following, it will return your json object  
			//out.print(daysJson);
			//out.flush();
			
			RequestDispatcher rd = getServletContext().getRequestDispatcher(destination);
			rd.forward(request, response);
			//byte[] outputData =respJson.getBytes();
			//response.setContentLength(outputData.length);
			//OutputStream httpOutputStream = response.getOutputStream();
			try {
				//response.setStatus(HttpServletResponse.SC_OK);
			    //httpOutputStream.write(outputData);
			} finally {
			    //httpOutputStream.close();
			}
		} catch (NumberFormatException e) {
			log.error("Error in parsing the request");
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			e.printStackTrace(new PrintStream(out,true));
			log.error(out.toString().replaceAll("\t", " "));
			sendtErrResp(response, "Error: Error in parsing the request's parameters", HttpServletResponse.SC_BAD_REQUEST);
		} catch (Exception e) {
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			e.printStackTrace(new PrintStream(out,true));
			log.error(out.toString().replaceAll("\t", " "));
			sendtErrResp(response, "Internal server Error", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		}
	} else {
		StringBuffer sb = new StringBuffer();
		sb.append("?");
		Enumeration<String> params = request.getParameterNames();
		while(params.hasMoreElements()){
			String par = params.nextElement();
			sb.append(par);
			sb.append("=");
			sb.append(request.getParameter(par));
			sb.append("&");
		}
		sb.deleteCharAt(sb.length()-1);	
		log.warn("Missing parameters in the request: " + request.getRequestURL() + sb.toString());
        sendtErrResp(response, "Error: All the parameters are obligatory", HttpServletResponse.SC_BAD_REQUEST);
	}
		       
		       
}
	private void sendtErrResp(HttpServletResponse response, String errMsg, int errType) throws IOException{
		StringBuffer sb = new StringBuffer();
		// TODO hardcoded, to put in the configuration file.
		sb.append("<html>");
	    sb.append("<head><title>Error</title></title>");
	    sb.append("<body>");
	    sb.append("<h1>"+ errMsg +"</h1>");
	    sb.append("</body></html>");
		byte[] outputData = sb.toString().getBytes();
        response.setContentLength(outputData.length);
        OutputStream httpOutputStream = response.getOutputStream();
        try {
        	response.setStatus(errType);
            httpOutputStream.write(outputData);
        } finally {
            httpOutputStream.close();
        }
	}
	
	public boolean fileExists( String path )
	{
		
		return ( new File( servletContext + path ) ).exists();
	}
	
	}

